﻿#include "DAData.h"
#include "DADataPyObject.h"
#include "DADataPyDataFrame.h"
//===================================================
// using DA namespace -- 禁止在头文件using！！
//===================================================

using namespace DA;

//===================================================
// DAData
//===================================================
DAData::DAData()
{
}

DAData::~DAData()
{
}

DAData::DAData(const DAAbstractData::pointer& d)
{
    _data = d;
}

/**
 * @brief 注意这里的等于不是指相等而是变量相等，类似is
 * @param d
 * @return
 */
bool DAData::operator==(const DAData& d) const
{
    return _data == d._data;
}

bool DAData::operator<(const DAData& d) const
{
    return rawPointer() < d.rawPointer();
}

DAData::DAData(const DAData& d)
{
    _data = d._data;
}

DAData::DAData(DAData&& d)
{
    _data = std::move(d._data);
}

DAData::DAData(const DAPyDataFrame& d)
{
    _data = std::static_pointer_cast< DAAbstractData >(std::make_shared< DADataPyDataFrame >(d));
}

DAData& DAData::operator=(const DAData& d)
{
    _data = d._data;
    return *this;
}

DAData& DAData::operator=(const DAAbstractData::pointer& d)
{
    _data = d;
    return *this;
}

DAData& DAData::operator=(const DAPyDataFrame& d)
{
    std::shared_ptr< DAAbstractData > p = std::static_pointer_cast< DAAbstractData >(std::make_shared< DADataPyDataFrame >(d));
    _data                               = p;
    return *this;
}

DAData::operator bool() const
{
    return _data != nullptr;
}

DAAbstractData::DataType DAData::getDataType() const
{
    if (!_data) {
        return DAAbstractData::TypeNone;
    }
    return _data->getDataType();
}

QVariant DAData::value() const
{
    if (!_data) {
        return QVariant();
    }
    return _data->toVariant();
}

bool DAData::setValue(const QVariant& v) const
{
    if (!_data) {
        return false;
    }
    return _data->setValue(v);
}

QString DAData::getName() const
{
    if (!_data) {
        return QString();
    }
    return _data->getName();
}

void DAData::setName(const QString& n)
{
    if (!_data) {
        return;
    }
    return _data->setName(n);
}

QString DAData::getDescribe() const
{
    if (!_data) {
        return QString();
    }
    return _data->getDescribe();
}

void DAData::setDescribe(const QString& d)
{
    if (!_data) {
        return;
    }
    return _data->setDescribe(d);
}

DAAbstractData* DAData::rawPointer()
{
    return _data.get();
}

const DAAbstractData* DAData::rawPointer() const
{
    return _data.get();
}

DAData::pointer DAData::getPointer()
{
    return _data;
}

DAData::const_pointer DAData::getPointer() const
{
    return _data;
}

bool DAData::isDataFrame() const
{
    if (!_data) {
        return false;
    }
    return (_data->getDataType() == DAAbstractData::TypePythonDataFrame);
}

/**
 * @brief 是否为datapackage
 * @return
 */
bool DAData::isDataPackage() const
{
    if (!_data) {
        return false;
    }
    return (_data->getDataType() == DAAbstractData::TypeDataPackage);
}

/**
 * @brief 转换为DAPyDataFrame
 * @return 如果内部维护的不是DAPyDataFrame，返回一个默认构造的DAPyDataFrame
 */
DAPyDataFrame DAData::toDataFrame() const
{
    if (isDataFrame()) {
        DADataPyDataFrame* df = static_cast< DADataPyDataFrame* >(_data.get());
        return df->dataframe();
    }
    return DAPyDataFrame();
}

/**
 * @brief 转换为datapackage,如果不是DADataPackage，返回nullptr
 * @return
 */
DADataPackage::pointer DAData::toDataPackage() const
{
    if (isDataPackage()) {
        DADataPackage::pointer d = std::static_pointer_cast< DADataPackage >(_data);
        return d;
    }
    return nullptr;
}

QString DAData::typeToString() const
{
    if (!_data) {
        return DAAbstractData::typeToString(DAAbstractData::TypeNone);
    }
    return DAAbstractData::typeToString(_data->getDataType());
}

namespace DA
{
uint qHash(const DAData& key, uint seed)
{
    return ::qHash(key.rawPointer(), seed);
}
}  // namespace DA
